<template>
  <div class="app-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>知识库：{{ knowledgeName }}</span>
        <el-button
          style="float: right; padding: 3px 0"
          type="text"
          icon="el-icon-back"
          @click="goBack"
        >返回知识库</el-button>
      </div>

      <!-- 上传组件 - 直接使用默认样式放在卡片内 -->
      <div class="upload-container">
        <el-upload
          class="upload-area"
          :action="uploadUrl"
          :on-preview="handlePreview"
          :on-remove="handleRemove"
          :on-success="handleSuccess"
          :on-error="handleError"
          :on-progress="handleProgress"
          :before-upload="beforeUpload"
          :file-list="fileList"
          :show-file-list="false"
          :headers="headers"
          multiple
          :on-exceed="handleExceed"
          drag
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">点击上传，或拖放文件到此处</div>
          <div class="el-upload__text">如果文件是以5个#分割的，请在文件名中添加'5#'，如 学生助手-基本信息-学校概况5#.txt(建议以txt格式上传)</div>
          <div class="el-upload__tip">支持的文件格式：Word(doc,docx), Excel(xls,xlsx), PPT(ppt,pptx), PDF(pdf), HTML(html,htm), TXT(txt), Markdown(md)，文档大小不超过50MB</div>
        </el-upload>
      </div>
    </el-card>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleBatchDelete"
          v-hasPermi="['knowledge:file:remove']"
        >批量删除</el-button>
      </el-col>
    </el-row>

    <el-table v-loading="loading" :data="fileList" style="margin-top: 20px" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="文件" align="center" prop="filename" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <div class="file-info-container">
            <div class="file-icon">
              <i :class="getFileIcon(scope.row.fileType)"></i>
            </div>
            <div class="file-name">{{ scope.row.filename }}</div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="文件类型" align="center" prop="fileType" width="100" />
      <el-table-column label="文件大小" align="center" width="120">
        <template slot-scope="scope">
          {{ formatFileSize(scope.row.fileSize) }}
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center" width="120">
        <template slot-scope="scope">
          <el-tag :type="getStatusType(scope.row.fileStatus)">{{ getStatusText(scope.row.fileStatus) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="向量数量" align="center" prop="vectorCount" width="100" />
      <el-table-column label="上传时间" align="center" prop="uploadTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.uploadTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="上传人" align="center" prop="uploader" width="100" />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
          >删除</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-refresh"
            @click="handleProcess(scope.row)"
            v-if="scope.row.fileStatus === '0' || scope.row.fileStatus === '3'"
          >重新处理</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-reading"
            @click="handleViewSegments(scope.row)"
            v-if="scope.row.fileStatus === '2'"
          >切片</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 文件上传进度 -->
    <el-dialog title="文件上传进度" :visible.sync="uploadVisible" :close-on-click-modal="false" width="400px">
      <div v-for="(file, index) in uploadingFiles" :key="index" class="upload-progress">
        <div class="file-info-container">
          <div class="file-icon">
            <i :class="getFileIcon(getFileExtension(file.name))"></i>
          </div>
          <div class="file-name">{{ file.name }}</div>
        </div>
        <el-progress :percentage="file.percentage" :status="file.status"></el-progress>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="uploadVisible = false" :disabled="uploading">关闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listFile, delFile, delFileByIds, processFile } from "@/api/knowledge/file";
import { getToken } from "@/utils/auth";

export default {
  name: "KnowledgeFile",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 是否显示批量删除按钮
      multiple: true,
      // 知识库ID
      knowledgeId: null,
      // 知识库名称
      knowledgeName: '',
      // 总条数
      total: 0,
      // 文件列表
      fileList: [],
      // 上传文件URL
      uploadUrl: process.env.VUE_APP_BASE_API + '/knowledge-base/',
      // 请求头
      headers: {
        Authorization: 'Bearer ' + getToken()
      },
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
      },
      // 上传对话框可见性
      uploadVisible: false,
      // 上传中文件列表
      uploadingFiles: [],
      // 是否上传中
      uploading: false,
      // 定时刷新功能
      refreshInterval: null,
      // 文件类型图标映射
      fileIcons: {
        // 文档
        doc: 'el-icon-document',
        docx: 'el-icon-document',
        txt: 'el-icon-document',
        pdf: 'el-icon-document',
        // 表格
        xls: 'el-icon-tickets',
        xlsx: 'el-icon-tickets',
        // 演示文稿
        ppt: 'el-icon-data-board',
        pptx: 'el-icon-data-board',
        // 图片
        jpg: 'el-icon-picture',
        jpeg: 'el-icon-picture',
        png: 'el-icon-picture',
        gif: 'el-icon-picture',
        bmp: 'el-icon-picture',
        // 压缩文件
        zip: 'el-icon-folder',
        rar: 'el-icon-folder',
        gz: 'el-icon-folder',
        bz2: 'el-icon-folder',
        // 视频
        mp4: 'el-icon-video-camera',
        avi: 'el-icon-video-camera',
        rmvb: 'el-icon-video-camera',
        // 其他
        html: 'el-icon-document',
        htm: 'el-icon-document',
        // 默认
        default: 'el-icon-document'
      }
    };
  },
  created() {
    const id = this.$route.params && this.$route.params.id;
    if (id) {
      this.knowledgeId = id;
      this.uploadUrl = process.env.VUE_APP_BASE_API + '/knowledge-base/' + id + '/files/upload';
      this.knowledgeName = this.$route.query.knowledgeName || '未命名知识库';
      this.getList();

      // 初始获取一次列表数据后，启动智能刷新
      this.startSmartRefresh();
    } else {
      this.$message.error('参数错误');
      this.goBack();
    }
  },
  beforeDestroy() {
    // 组件销毁前清除定时器
    this.stopRefresh();
  },
  methods: {
    // 获取文件扩展名
    getFileExtension(fileName) {
      if (!fileName) return '';
      const parts = fileName.split('.');
      return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : '';
    },

    // 获取文件图标
    getFileIcon(fileType) {
      if (!fileType) return this.fileIcons.default;
      const type = fileType.toLowerCase();
      return this.fileIcons[type] || this.fileIcons.default;
    },

    // 开始智能刷新 - 只有当有文件处理中时才会频繁刷新
    startSmartRefresh() {
      // 停止现有的定时器
      this.stopRefresh();

      // 启动新的定时器，根据状态动态调整刷新频率
      this.refreshInterval = setInterval(() => {
        // 检查是否有正在处理中的文件
        const hasProcessingFiles = this.fileList && this.fileList.some(file => file.fileStatus === '1');

        if (hasProcessingFiles) {
          // 有处理中的文件，5秒刷新一次
          this.getList();
        } else {
          // 没有处理中的文件，停止频繁刷新，改为30秒刷新一次
          this.stopRefresh();
          this.refreshInterval = setInterval(() => {
            this.getList();
          }, 30000); // 30秒
        }
      }, 5000); // 初始为5秒
    },

    // 停止刷新
    stopRefresh() {
      if (this.refreshInterval) {
        clearInterval(this.refreshInterval);
        this.refreshInterval = null;
      }
    },

    /** 查询文件列表 */
    getList() {
      this.loading = true;
      listFile(this.knowledgeId, this.queryParams).then(response => {
        this.fileList = response.rows;
        this.total = response.total;
        this.loading = false;

        // 检查是否需要调整刷新频率
        const hasProcessingFiles = this.fileList && this.fileList.some(file => file.fileStatus === '1');
        if (hasProcessingFiles && !this.refreshInterval) {
          // 有处理中的文件，但没有定时器，启动智能刷新
          this.startSmartRefresh();
        }

        // 保留调试日志，但减少输出频率
        if (this.fileList && this.fileList.length > 0 && hasProcessingFiles) {
          console.log('文件状态值:', this.fileList.map(item => ({
            id: item.id,
            name: item.filename,
            status: item.fileStatus
          })));
        }
      });
    },
    // 返回按钮
    goBack() {
      this.$router.push('/knowledge/base');
    },
    // 文件大小格式化
    formatFileSize(size) {
      if (!size) return '0 B';

      const units = ['B', 'KB', 'MB', 'GB', 'TB'];
      let index = 0;
      let fileSize = parseInt(size);

      while (fileSize >= 1024 && index < units.length - 1) {
        fileSize /= 1024;
        index++;
      }

      return fileSize.toFixed(2) + ' ' + units[index];
    },
    // 获取文件状态类型
    getStatusType(status) {
      switch (status) {
        case '0': return 'info';    // 未处理
        case '1': return 'warning'; // 处理中
        case '2': return 'success'; // 已完成
        case '3': return 'danger';  // 失败
        default: return 'info';
      }
    },
    // 获取文件状态文字
    getStatusText(status) {
      // 确保status是字符串类型
      const statusStr = String(status);
      switch (statusStr) {
        case '0': return '未处理';
        case '1': return '处理中';
        case '2': return '向量完成';
        case '3': return '处理失败';
        default: return '未知状态(' + statusStr + ')';
      }
    },
    // 上传前检查
    beforeUpload(file) {
      // 文件大小检查
      const isLt50M = file.size / 1024 / 1024 < 50;
      if (!isLt50M) {
        this.$message.error('文件大小不能超过 50MB!');
        return false;
      }

      // 文件类型检查
      const fileName = file.name;
      const fileExt = this.getFileExtension(fileName);
      console.log('文件扩展名:', fileExt); // 添加调试日志

      const allowedExtensions = [
        'md', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'html', 'htm', 'txt', 'pdf'
      ];

      if (!allowedExtensions.includes(fileExt.toLowerCase())) {
        this.$message.error(`不支持的文件类型: ${fileExt}，请上传支持的文件类型`);
        return false;
      }

      // 显示上传进度对话框
      if (!this.uploadVisible) {
        this.uploadingFiles = [];
        this.uploadVisible = true;
      }

      // 添加到上传文件列表
      this.uploadingFiles.push({
        name: file.name,
        percentage: 0,
        status: ''
      });

      this.uploading = true;
      return true;
    },
    // 上传超出数量限制
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 10 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`);
    },
    // 上传进度
    handleProgress(event, file, fileList) {
      const uploadFile = this.uploadingFiles.find(item => item.name === file.name);
      if (uploadFile) {
        uploadFile.percentage = Math.floor(event.percent);
      }
    },
    // 上传成功
    handleSuccess(response, file, fileList) {
      const uploadFile = this.uploadingFiles.find(item => item.name === file.name);
      if (uploadFile) {
        uploadFile.percentage = 100;
        uploadFile.status = 'success';
      }

      // 更新上传状态
      let allCompleted = true;
      this.uploadingFiles.forEach(item => {
        if (item.percentage < 100) {
          allCompleted = false;
        }
      });

      if (allCompleted) {
        this.uploading = false;
        // 使用右侧弹出的通知方式替代原message
        this.$notify({
          title: '上传成功',
          message: '文件上传成功，后台开始处理文件',
          type: 'success',
          position: 'right',
          duration: 3000
        });
        this.getList(); // 刷新文件列表
        // 文件上传后启动智能刷新，确保能看到处理状态变化
        this.startSmartRefresh();
      }
    },
    // 上传失败
    handleError(err, file, fileList) {
      const uploadFile = this.uploadingFiles.find(item => item.name === file.name);
      if (uploadFile) {
        uploadFile.status = 'exception';
      }

      this.uploading = false;
      this.$notify({
        title: '上传失败',
        message: '文件上传失败: ' + (err.message || '未知错误'),
        type: 'error',
        position: 'right',
        duration: 4000
      });
    },
    // 文件移除
    handleRemove(file, fileList) {
      // 在进度框中移除文件
      const index = this.uploadingFiles.findIndex(item => item.name === file.name);
      if (index !== -1) {
        this.uploadingFiles.splice(index, 1);
      }
    },
    // 点击文件预览
    handlePreview(file) {
      console.log(file);
    },
    /** 批量删除按钮操作 */
    handleBatchDelete() {
      const fileIds = this.ids;
      if (fileIds.length === 0) {
        this.$message.warning("请至少选择一条记录");
        return;
      }
      this.$modal.confirm('是否确认批量删除选中的' + fileIds.length + '个文件？').then(function() {
        return delFileByIds(fileIds);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("批量删除成功");
      }).catch(() => {});
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id);
      this.multiple = !selection.length;
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$modal.confirm('是否确认删除该文件？').then(function() {
        return delFile(row.id);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
    /** 处理按钮操作 */
    handleProcess(row) {
      this.$modal.confirm('是否重新处理该文件？').then(function() {
        return processFile(row.id);
      }).then(() => {
        this.getList();
        // 处理文件后启动智能刷新
        this.startSmartRefresh();
        this.$modal.msgSuccess("文件已开始处理");
      }).catch(() => {});
    },
    // 查看文件切片
    handleViewSegments(row) {
      this.$router.push({
        path: `/knowledge/segment/${row.id}`,
        query: {
          fileName: row.filename,
          knowledgeId: this.knowledgeId,
          knowledgeName: this.knowledgeName
        }
      });
    }
  }
};
</script>

<style scoped>
.upload-progress {
  margin-bottom: 15px;
}
.file-name {
  margin-bottom: 5px;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 文件信息容器 */
.file-info-container {
  display: flex;
  align-items: center;
}

.file-icon {
  margin-right: 8px;
  font-size: 18px;
}

.file-icon i {
  vertical-align: middle;
}

/* 上传区域容器 */
.upload-container {
  padding: 20px 0;
  box-sizing: border-box;
}

.upload-area {
  width: 100%;
}

.upload-area .el-upload {
  width: 100%;
  text-align: center;
  cursor: pointer;
  outline: none;
}

.upload-area .el-upload-dragger {
  width: 100%;
  height: 200px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 20px;
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  background-color: #fafafa;
  transition: border-color 0.3s;
}

.upload-area .el-upload-dragger:hover {
  border-color: #409EFF;
}

.upload-area .el-icon-upload {
  font-size: 48px;
  color: #409EFF;
  margin-bottom: 15px;
}

.upload-area .el-upload__text {
  color: #606266;
  font-size: 16px;
  margin-bottom: 10px;
}

.upload-area .el-upload__tip {
  color: #909399;
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
  padding: 0 16px;
}

/* 隐藏旧的容器样式 */
.file-upload-container, .file-upload-main-container, .orange-border-container {
  display: none;
}
</style>
